#include <iostream>

#include "CSignal.h"

using namespace std;

class CSIGHUPHandler : public CSignalHandler {
private:
	sig_atomic_t _terminal_quit;

public :
	CSIGHUPHandler() {
		_terminal_quit = 0;
	};
	~CSIGHUPHandler() {};

	virtual int handle(int signum, siginfo_t *si, void *sv) {
		assert(signum==SIGHUP);
		this->_terminal_quit = 1;
	};

	sig_atomic_t terminal_quit() {
		return this->_terminal_quit;
	};
};

class CSIGINTHandler : public CSignalHandler {
private:
	sig_atomic_t _graceful_quit;

public :
	CSIGINTHandler() {
		_graceful_quit = 0;
	};
	~CSIGINTHandler() {};

	virtual int handle(int signum, siginfo_t *si, void *sv) {
		assert(signum==SIGINT);
		this->_graceful_quit = 1;
	};

	sig_atomic_t graceful_quit() {
		return this->_graceful_quit;
	};
};

class CSIGQUITHandler : public CSignalHandler {
private:
	sig_atomic_t _abortive_quit;

public :
	CSIGQUITHandler() {
		_abortive_quit = 0;
	};
	~CSIGQUITHandler() {};

	virtual int handle(int signum, siginfo_t *si, void *sv) {
		assert(signum==SIGQUIT);
		this->_abortive_quit = 1;
	};

	sig_atomic_t abortive_quit() {
		return this->_abortive_quit;
	};
};

int do_work()
{
	sleep(1);
	cerr << "hahaha" << endl;
}

int clean_up()
{
	cerr << "clean up" << endl;
}

int main(void)
{
	CSIGHUPHandler sighup_handler;
	CSIGINTHandler sigint_handler;
	CSIGQUITHandler sigquit_handler;

	CSignal::instance()->register_handler(SIGHUP, &sighup_handler);
	CSignal::instance()->register_handler(SIGINT, &sigint_handler);
	CSignal::instance()->register_handler(SIGQUIT, &sigquit_handler);

	while(sighup_handler.terminal_quit()==0&&sigint_handler.graceful_quit()==0&&sigquit_handler.abortive_quit()==0) do_work();

	if(sighup_handler.terminal_quit()==1) {
		CSignal::instance()->remove_handler(SIGINT);
		while(sigint_handler.graceful_quit()==0&&sigquit_handler.abortive_quit()==0) do_work();
	}

	if(sigquit_handler.abortive_quit()==1) {
		cerr << "oops~ aborted" << endl;
		_exit(1);
	}
	else if(sigint_handler.graceful_quit()==1) {
		clean_up();
		return 1;
	}
}
